import { BufferAttribute, BufferGeometry, CatmullRomCurve3, Color, Group, Line, LineBasicMaterial, Points, PointsMaterial, Vector3 } from "three";
import { App } from "../../application";
import Events from "../../application/constants/Events";
import { Point } from "../../Engine";
import Const from "../../application/constants/Const";
import ShaderConst from "../../renderExtension/Material/ShaderConst";
import { CustomPointsMaterial } from "../../renderExtension/Material/CustomMaterial";

/** 点对点连接线 */
export default class FlyLine extends Group {
    private line;
    private points;
    private app: App;
    private index = 0;
    private num = 50;
    private pointsGeometry;
    public pointColor;
    public lineColor;
    public positions = [];
    constructor(cfg: any) {
        super();
        this.app = App.getInstance();
        if (!cfg.positions || cfg.positions.length != 3) {
            console.warn('flyline组件的点数量只能为3个')
            return;
        }
        this.positions = cfg.positions;
        this.pointColor = cfg.pointColor ? cfg.pointColor : 0x006666;//默认青色
        this.lineColor = cfg.lineColor ? cfg.lineColor : 0xffff00;//默认黄色
        this.makeLine();
        this.makePoints();
        this.app.on(Events.Render, this.update.bind(this));
    }

    private makePoints() {
        var index = 20; //取点索引位置
        var num = 15; //从曲线上获取点数量
        var points2 = this.points.slice(index, index + num); //从曲线上获取一段
        var curve = new CatmullRomCurve3(points2);
        var newPoints2 = curve.getSpacedPoints(100); //获取更多的点数
        this.pointsGeometry = new BufferGeometry();
        this.pointsGeometry.setFromPoints(newPoints2);
        // 每个顶点对应一个百分比数据attributes.percent 用于控制点的渲染大小
        var percentArr = []; //attributes.percent的数据
        for (var i = 0; i < newPoints2.length; i++) {
            percentArr.push(i / newPoints2.length);
        }
        var percentAttribue = new BufferAttribute(new Float32Array(percentArr), 1);
        this.pointsGeometry.attributes.percent = percentAttribue;
        // 批量计算所有顶点颜色数据
        var colorArr = [];
        for (var i = 0; i < newPoints2.length; i++) {
            var color1 = new Color(this.pointColor); //轨迹线颜色 青色
            var color2 = new Color(this.lineColor); //黄色
            var color = color1.lerp(color2, i / newPoints2.length)
            colorArr.push(color.r, color.g, color.b);
        }
        // 设置几何体顶点颜色数据
        this.pointsGeometry.attributes.color = new BufferAttribute(new Float32Array(colorArr), 3);

        let macrosList = new Array<string>();
        macrosList.push(ShaderConst.macrosConfig.flylineMacros);
        // 点模型渲染几何体每个顶点
        var pointsMaterial = new CustomPointsMaterial({coreParameters: {
            // color: 0xffff00,
            size: 5 * 5.0, //点大小
            vertexColors: true, //使用顶点颜色渲染
            transparent: true,//开启透明计算
            depthTest: false,
        }, macrosList: macrosList});
        var flyPoints = new Points(this.pointsGeometry, pointsMaterial);
        this.add(flyPoints);
    }

    /**
     * 生成线对象
     */
    private makeLine() {
        var geometry = new BufferGeometry(); //创建一个缓冲类型几何体

        // 三维样条曲线
        var curve = new CatmullRomCurve3([
            this.positions[0].changeEPSGType(Const.EPSGType.EPSGWeb), this.positions[1].changeEPSGType(Const.EPSGType.EPSGWeb), this.positions[2].changeEPSGType(Const.EPSGType.EPSGWeb)
        ]);
        //曲线上等间距返回多个顶点坐标
        this.points = curve.getSpacedPoints(100); //分段数100，返回101个顶点
        // setFromPoints方法从points中提取数据赋值给attributes.position
        geometry.setFromPoints(this.points);
        var material = new LineBasicMaterial({
            color: 0x006666, //轨迹颜色
        });
        //线条模型对象
        this.line = new Line(geometry, material);
        this.add(this.line);
    }

    private symbol = 0.1;
    private update() {
        if (this.index > (this.points.length - this.num) || this.index < 0)
            this.index = 0;
        // this.symbol = this.symbol * -1;
        this.index += 1 * this.symbol;
        let points2 = this.points.slice(this.index, this.index + this.num); //从曲线上获取一段
        var curve = new CatmullRomCurve3(points2);
        var newPoints2 = curve.getSpacedPoints(100); //获取更多的点数
        this.pointsGeometry.setFromPoints(newPoints2);
    }
}